package common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;


public class JsonUtil {
	private static final Logger log = LoggerFactory.getLogger(JsonUtil.class);
	private static ObjectMapper mapper = null;
	private static ObjectMapper getMapper()
	{
		if(mapper == null)
		{
			mapper = new ObjectMapper();
			mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
			mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
			mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
			mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
			mapper.configure(JsonParser.Feature.IGNORE_UNDEFINED, true);
			//mapper.configure(JsonParser.Feature.CANONICALIZE_FIELD_NAMES, true);
			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//			mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//			mapper.configure(DeserializationFeature.AUTO_DETECT_FIELDS, true);
//			mapper.configure(DeserializationFeature.AUTO_DETECT_SETTERS, true);
//			mapper.configure(DeserializationFeature.AUTO_DETECT_CREATORS, true);
			mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
		}
		return mapper;
	}
	public static String toJson(Object o)
	{
		String result = null;
		
		try {
			result = getMapper().writeValueAsString(o);
		} catch (JsonGenerationException e) {
			
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			System.gc();
			log.error("no memory to trigger system gc");
			e.printStackTrace();
		}
		return result;
	}
	
	public static String toJsonAsPretty(Object o)
	{
		String result = null;
		
		try {
			result = getMapper().writerWithDefaultPrettyPrinter().writeValueAsString(o);
		} catch (JsonGenerationException e) {
			
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			System.gc();
			log.error("no memory to trigger system gc");
			e.printStackTrace();
		}
		return result;
	}
	
	public static <T> T fromJson(Class<T> cls, String jsonStr)
	{
		T result = null;
		try {
			if(jsonStr != null && jsonStr.length() > 0)
			{
			result =  getMapper().readValue(jsonStr, cls);
			}
		} catch (Exception e) {
			log.warn(String.format("fromJson:%s", jsonStr));
			e.printStackTrace();
		}
		return result;
	}

	public static <T> List<T> jsonToList(String jsonString, Class<T> clazz) {
		List<T> ts = (List<T>) JSONArray.parseArray(jsonString, clazz);
		return ts;
	}

	public static String toJsonSortField(Object obj) {
		return JSONObject.toJSONString(obj, SerializerFeature.SortField);
	}
}
